package com.crm.app.controller;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.crm.app.domain.AppLoginJour;
import com.crm.app.domain.UserCallJour;
import com.crm.app.service.IAppLoginJourService;
import com.crm.app.service.IUserCallJourService;
import com.crm.custinfo.domain.CustInfo;
import com.crm.custinfo.service.ICustInfoService;
import com.crm.custinfo.service.impl.UserInfoComm;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.constant.ConfigConstant;
import com.ruoyi.common.constant.StatusConstant;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.AesUtils;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.Md5Encrypt;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.framework.datasource.DynamicDataSourceContextHolder;
import com.ruoyi.framework.websocket.AppWebSocket;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.ISysUserService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.*;

/**
 * 功能说明: 管理端&APP拨号相关交互API<br>
 * 开发人员: @author Mr.Wen<br>
 *
 * @date 2024-05-17
 */
@RestController
@RequestMapping("/phone")
public class PhoneController extends BaseController {
    public static final org.slf4j.Logger logger = LoggerFactory.getLogger("PhoneController");
    @Autowired
    private ISysConfigService iSysConfigService;
    @Autowired
    private ISysUserService iSysUserService;
    @Autowired
    private IAppLoginJourService iAppLoginJourService;
    @Autowired
    private ICustInfoService iCustInfoService;
    @Autowired
    private AppWebSocket appWebSocket;
    @Autowired
    private IUserCallJourService iUserCallJourService;
    @Autowired
    private ISysConfigService baseSysConfigService;
    @Autowired
    private ISysDeptService isysDeptService;
    @Autowired
    private UserInfoComm userInfoComm;

    private Map<String, String> phoneMapping = new HashMap<String, String>() {{
        put("1", "tds");
        put("2", "=sd");
        put("3", "fde");
        put("4", "9dd");
        put("5", "f12");
        put("6", "fdx");
        put("7", "sds");
        put("8", "ffs");
        put("9", "ccf");
        put("0", "6ss");
    }};

    /**
     * 获取手机app的版本信息
     *
     * @return
     */
    @Anonymous
    @GetMapping("/getVersionInfo")
    public AjaxResult getVersionInfo() {
        return AjaxResult.success(iSysConfigService.getItemValueByItemKey("versionCode"));
    }

    /**
     * app 手机号+认证密码授权登录
     *
     * @return
     */
    @Anonymous
    @GetMapping("/authLogin/{mobile}/{password}/{imei}")
    public AjaxResult authLogin(@PathVariable("mobile") String mobile, @PathVariable("password") String password, @PathVariable("imei") String imei) throws Exception {
        int code = 0;
        String msg = "授权成功";
        Map<String, Object> params = new HashMap<String, Object>();
        SysUser user = iSysUserService.selectUserByUserName(mobile);
logger.info("用户登录：{}{},租户信息{}", mobile, password,DynamicDataSourceContextHolder.getDataSourceKey());
        if (user == null) {
            code = -1;
            msg = "用户不存在";
        } else {
            logger.info("用户登录：{}{}", mobile, password);
            String password2 = AesUtils.decrypt(user.getPassword2());
            if (!Md5Encrypt.md5(password2).equals(password)) {
                code = -1;
                msg = "授权失败";

            } else {

                params.put("id", user.getUserId());
                params.put("name", user.getNickName());
                params.put("token", AesUtils.encrypt(user.getUserId() + "-" + mobile));

                String userAgent = getRequest().getHeader("user-agent");
                AppLoginJour jour = new AppLoginJour();
                jour.setMobile(mobile);
                jour.setDeviceInfo(userAgent.length() >= 2000 ? userAgent.substring(0, 2000) : userAgent);
                jour.setLoginTime(new Date());
                iAppLoginJourService.insertAppLoginJour(jour);
            }

        }
        params.put("code", code);
        params.put("msg", msg);
        return AjaxResult.success(params);
    }

    /**
     * app 手机号+认证密码授权登录
     *
     * @return
     */
    @Anonymous
    @GetMapping("/callPhone/{id}")
    public AjaxResult callPhone(@PathVariable("id") Long id) {
        CustInfo custInfo = iCustInfoService.selectCustInfoById(id);
        SysUser user = getLoginUser().getUser();
        int code = 0;
        String msg = "拨打成功";
        if (custInfo == null) {
            code = -1;
            msg = "客户不存在";
        } else {
            if (!Objects.equals(user.getUserId(), custInfo.getUserId())) {
                code = -1;
                msg = "拨号请求发送失败，请确认是否本人客户";
            } else {
                String tenantId = DynamicDataSourceContextHolder.getDataSourceKey();
                AjaxResult result = iCustInfoService.decryptMobile(custInfo);
                String phone = result.get("msg").toString();
                Map<String, Object> map = new HashMap<String, Object>();
                map.put("mobile", phone);
                map.put("call_prefix", "");
                if (!appWebSocket.sendCallPhoneMessage(JSON.toJSONString(map), tenantId+"_!_"+user.getPhonenumber())) {
                    code = -1;
                    msg = "拨号请求发送失败，请确保APP在线";
                }
            }
        }
        Map<String, Object> result = new HashMap<>();
        result.put("code", code);
        result.put("msg", msg);
        return AjaxResult.success(result);
    }

    /**
     * 批量保存APP呼叫流水
     *
     * @return
     * @throws Exception
     */
    @Anonymous
    @PostMapping("/saveBatchCallJour")
    public AjaxResult saveBatchCallJour() {
        int code = 0;
        String msg = "记录成功";
        Map<String, Object> params = new HashMap<>();
        try {
            String requestBoday = getRequestBoday();
            JSONObject json = JSONObject.parseObject(requestBoday);
            JSONArray list = json.getJSONArray("data");
            if (list == null || list.isEmpty()) {
                code = -1;
                msg = "请求参数缺失";
            } else {

                int succeed = 0;
                for (Object o : list) {
                    JSONObject map = (JSONObject) o;
                    String token = map.getString("token");
                    String type = map.getString("type");// 1-呼入 2-呼出
                    String callFrom = map.getString("callFrom");//呼叫发起方
                    String callTo = map.getString("callTo");//呼叫目标方
                    long call_time = map.getLongValue("call_time");//呼叫时间 时间戳格式
                    Long talkTime = map.getLongValue("talkTime");//通话时间
                    Integer empId = map.getIntValue("empId");
                    if (!"12".contains(type) || StringUtils.isBlank(callFrom) || StringUtils.isBlank(callTo)
                            || call_time <= 0 || empId <= 0 || StringUtils.isBlank(token)) {
                        continue;
                    }
                    // 呼入时，目标方为员工；呼出时，发起方为员工
                    String mobile = "1".equals(type) ? callTo : callFrom;

                    SysUser user = iSysUserService.getUseyByphonenumber(mobile);
                    if (user == null || !Objects.equals(user.getUserId(), empId)) {

                        params.put("code", -1);
                        params.put("msg", "用户不存在");
                        return AjaxResult.success(params);
                    }

                    String checkToken = AesUtils.encrypt(user.getUserId() + "-" + mobile).replace("/", "*****");
                    ;
                    if (!token.equals(checkToken)) {
                        continue;
                    }
                    UserCallJour entity = new UserCallJour();
                    entity.setType(type);
                    entity.setCallFrom(callFrom);
                    entity.setCallTo(callTo);
                    entity.setCallTime(DateUtils.timeToDate(call_time, DateUtils.YYYY_MM_DD_HH_MM_SS));
                    entity.setTalkTime(talkTime);
                    entity.setEmpId(user.getUserId());
                    List<UserCallJour> list1 = iUserCallJourService.selectUserCallJourList(entity);
                    if (CollectionUtils.isNotEmpty(list1)) {
                        continue;
                    }
                    // token有效
                    UserCallJour jour = new UserCallJour();
                    jour.setType(type);
                    jour.setCallFrom(callFrom);
                    jour.setCallTo(callTo);
                    jour.setCallTime(DateUtils.timeToDate(call_time, DateUtils.YYYY_MM_DD_HH_MM_SS));
                    jour.setTalkTime(talkTime);
                    jour.setIsConnected(talkTime > 0 ? "1" : "0");
                    jour.setEmpId(user.getUserId());
                    jour.setCreateTime(new Date());
                    iUserCallJourService.insertUserCallJour(jour);
                    succeed++;
                }
                logger.info("saveBatchCallJour succeed size: {}", succeed);
                if (succeed == 0) {
                    code = -1;
                    msg = "记录已存在";
                }
            }
        } catch (Exception e) {
            code = -1;
            msg = "添加异常";
        }
        params.put("code", code);
        params.put("msg", msg);
        return AjaxResult.success(params);
    }

    /**
     * 保存APP呼叫流水
     *
     * @return
     */
    @Anonymous
    @PostMapping("/saveCallJour/{type}/{id}/{token}/{callFrom}/{callTo}/{talkTime}/{callTime}")
    public AjaxResult saveCallJour(@PathVariable("type") int type, @PathVariable("id") Long id,
                                   @PathVariable("token") String token, @PathVariable("callFrom") String callFrom,
                                   @PathVariable("callTo") String callTo, @PathVariable("talkTime") Long talkTime,
                                   @PathVariable("callTime") long callTime) {
        int code = 0;
        String msg = "记录成功";
        Map<String, Object> params = new HashMap<>();
        try {
            if (!(type == 1 || type == 2) || StringUtils.isBlank(callFrom) || StringUtils.isBlank(callTo)
                    || callTime <= 0 || id <= 0 || StringUtils.isBlank(token)) {
                code = -1;
                msg = "参数异常";
            }
            // 呼入时，目标方为员工；呼出时，发起方为员工
            String mobile = 1 == type ? callTo : callFrom;

            SysUser user = iSysUserService.getUseyByphonenumber(mobile);
            if (user == null || !Objects.equals(user.getUserId(), id)) {

                params.put("code", -1);
                params.put("msg", "用户不存在");
                return AjaxResult.success(params);
            }


            String checkToken = AesUtils.encrypt(user.getUserId() + "-" + mobile).replace("/", "*****");
            ;
            if (!token.equals(checkToken)) {
                params.put("code", -1);
                params.put("msg", "参数错误");
                return AjaxResult.success(params);
            }

            UserCallJour entity = new UserCallJour();
            entity.setType(String.valueOf(type));
            entity.setCallFrom(callFrom);
            entity.setCallTo(callTo);
            entity.setCallTime(DateUtils.timeToDate(callTime, DateUtils.YYYY_MM_DD_HH_MM_SS));
            entity.setTalkTime(talkTime);
            entity.setEmpId(user.getUserId());
            List<UserCallJour> list = iUserCallJourService.selectUserCallJourList(entity);
            if (CollectionUtils.isNotEmpty(list)) {
                params.put("code", -1);
                params.put("msg", "记录已存在");
                return AjaxResult.success(params);
            }

            // token有效
            UserCallJour jour = new UserCallJour();
            jour.setType(String.valueOf(type));
            jour.setCallFrom(callFrom);
            jour.setCallTo(callTo);
            jour.setCallTime(DateUtils.timeToDate(callTime, DateUtils.YYYY_MM_DD_HH_MM_SS));
            jour.setTalkTime(talkTime);
            jour.setIsConnected(talkTime > 0 ? "1" : "0");
            jour.setEmpId(user.getUserId());
            jour.setCreateTime(new Date());
            iUserCallJourService.insertUserCallJour(jour);
        } catch (Exception e) {
            code = -1;
            msg = "添加异常";
        }
        params.put("code", code);
        params.put("msg", msg);
        return AjaxResult.success(params);
    }


    /**
     * 查询用户通话记录流水
     *
     * @return
     */
    @Anonymous
    @PostMapping("/getCallJourList/{id}/{token}")
    public AjaxResult getCallJourList(@PathVariable("id") Long id, @PathVariable("token") String token) {
        Map<String, Object> resMap = new HashMap<>();
        try {
            SysUser sysUser = iSysUserService.selectUserById(id);
            if (sysUser == null || !Objects.equals(sysUser.getStatus(), "0")) {
                resMap.put("code", -1);
                resMap.put("msg", "用户不存在");
                resMap.put("list", null);
                return AjaxResult.success(resMap);
            }

            String checkToken = AesUtils.encrypt(sysUser.getUserId() + "-" + sysUser.getPhonenumber()).replace("/", "*****");
            if (!token.equals(checkToken)) {
                resMap.put("code", -1);
                resMap.put("msg", "用户不存在");
                resMap.put("list", null);
                return AjaxResult.success(resMap);
            }

            // 呼叫流水手机端同步天数：
            int days = baseSysConfigService.getItemValueByItemKey(ConfigConstant.CALLPHONE_JOUR_QRY_DAYS, 3);
            UserCallJour userCallJour = new UserCallJour();
            userCallJour.setEmpId(id);
            userCallJour.setStartTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, DateUtils.addDay(new Date(), -days)) + " 00:00:00");

            List<UserCallJour> list = iUserCallJourService.selectUserCallJourList(userCallJour);

            resMap.put("code", 0);
            resMap.put("msg", "读取成功");
            resMap.put("list", list);
            return AjaxResult.success(resMap);
        } catch (Exception e) {
            resMap.put("code", -1);
            resMap.put("msg", "读取异常");
            resMap.put("list", null);
            logger.error("查询用户通话记录流水异常" + e);
            return AjaxResult.success(resMap);
        }
    }

    /**
     * 获取我的客户数据
     *
     * @param pageSize
     * @param pageIndex
     * @param token
     * @return
     */
    @Anonymous
    @GetMapping("/getCustInfoList/{id}/{pageSize}/{pageIndex}/{token}")
    public AjaxResult getCustInfoList(@PathVariable("id") Long id, @PathVariable("pageSize") int pageSize, @PathVariable("pageIndex") int pageIndex, @PathVariable("token") String token) {
        Map<String, Object> resMap = new HashMap<>();
        SysUser sysUser = iSysUserService.selectUserById(id);
        if (sysUser == null || !Objects.equals(sysUser.getStatus(), "0")) {
            resMap.put("code", -1);
            resMap.put("msg", "用户不存在");
            resMap.put("list", null);
            return AjaxResult.success(resMap);
        }
        token = token.replace("/", "*****");
        if (!checkToken(token, String.valueOf(id), sysUser.getPhonenumber())) {
            resMap.put("code", -1);
            resMap.put("msg", "安全验证不通过");
            resMap.put("list", null);
            return AjaxResult.success(resMap);
        }
        Map<String, Object> inParams = new HashMap<String, Object>();
        inParams.put("pageSize", pageSize);
        inParams.put("pageIndex", pageIndex * pageSize);
        CustInfo custInfo = new CustInfo();
        custInfo.setParams(inParams);
        custInfo.setUserId(id);

        List<CustInfo> custInfoList = iCustInfoService.selectMyCustList(custInfo);
        for (CustInfo info : custInfoList) {
            info.setMobile2(getPhone(info));
            info.setMd5val("");
            info.setEncval("");
        }

        resMap.put("code", 0);
        resMap.put("msg", "获取成功");
        resMap.put("list", getDataTable(custInfoList));
        return AjaxResult.success(resMap);


    }

    /**
     * 验证token
     *
     * @param token 解析出的格式是  用户id@~@时间@~@电话@~@3位随机
     * @return
     */

    public Boolean checkToken(String token, String id, String phonenumber) {
        try {
            String token2 = id + "@~@" + DateUtils.getCurrentDay() + "@~@" + phonenumber + "@~@" + generateRandomCode();
            token2 = Md5Encrypt.md5(token2);
            return token.equals(token2);
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 根据星期数，生成随机码
     *
     * @return
     */
    public static String generateRandomCode() {
        Calendar calendar = Calendar.getInstance();
        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
        String key = "";
        switch (dayOfWeek) {
            case 0:
                key = "aec";
                break;
            case 1:
                key = "8dd";
                break;
            case 2:
                key = "5rg";
                break;
            case 3:
                key = "7jg";
                break;
            case 4:
                key = "7jk";
                break;
            case 5:
                key = "0pk";
                break;
            case 6:
                key = "1w3";
                break;
            default:
                key = "ddf";
                break;

        }
        return key;
    }

    /**
     * 获取post的请求参数
     *
     * @return
     */
    public String getRequestBoday() {
        HttpServletRequest request = (HttpServletRequest) ServletUtils.getRequest();
        InputStream inputStream;
        String strResponse = "";
        try {
            inputStream = request.getInputStream();
            String strMessage = "";
            BufferedReader reader;
            reader = new BufferedReader(new InputStreamReader(inputStream, "utf-8"));
            while ((strMessage = reader.readLine()) != null) {
                strResponse += strMessage;
            }
            reader.close();
            inputStream.close();
        } catch (IOException e) {

        }
        return strResponse;
    }

    /**
     * 特殊加密电话号码
     *
     * @param custInfo
     * @return
     */
    public String getPhone(CustInfo custInfo) {
        AjaxResult result = iCustInfoService.decryptMobile(custInfo);
        String phone = result.get("msg").toString();
        StringBuilder phoneEncrypt = new StringBuilder();
        if (phone.length() == 11) {
            char[] phones = phone.toCharArray();
            for (char c : phones) {
                phoneEncrypt.append(phoneMapping.get(String.valueOf(c)));
            }

        }
        return phoneEncrypt.toString();
    }

    /**
     * 获取未处理客户信息
     *
     * @return
     */
    @GetMapping("/getNotProcessedCust/{userId}")
    public AjaxResult getNotProcessedCust(@PathVariable Long userId) {
        Map<String, Object> result = new HashMap<String, Object>();
        //总数
        int totalNum = 0;
        //我的客户
        int myNum = 0;
        //再分配客户
        int reNum = 0;
        //必跟进客户
        int mustNum = 0;

        CustInfo custInfo = new CustInfo();
        custInfo.setUserId(userId);
        custInfo.setIsDelete("0");
        custInfo.setStatus("0");
        //查询所有跟进中的客户
        List<CustInfo> listCust = iCustInfoService.selectCustInfoList(custInfo);
        for (CustInfo info : listCust) {
            if (StatusConstant.DISTRIBUTE_STATUS_YES.equals(info.getReDistributeStatus())) {
                myNum++;
            } else if (StatusConstant.DISTRIBUTE_STATUS_RE.equals(info.getReDistributeStatus())) {
                reNum++;
            } else if (StatusConstant.DISTRIBUTE_STATUS_MUST.equals(info.getReDistributeStatus())) {
                mustNum++;
            }
        }
        totalNum = listCust.size();
        result.put("totalNum", totalNum);
        result.put("myNum", myNum);
        result.put("reNum", reNum);
        result.put("mustNum", mustNum);

        return AjaxResult.success(result);
    }

    /**
     * 获取未处理客户信息
     *
     * @return
     */
    @GetMapping("/getNotProcessedCustTotal/{userId}")
    public AjaxResult getNotProcessedCustTotal(@PathVariable Long userId) {
        Map<String, Object> result = new HashMap<String, Object>();
        //总数
        int totalNum = 0;
        //再分配客户
        int reNum = 0;
        //必跟进客户
        int mustNum = 0;

        SysUser sysUser = iSysUserService.selectUserById(userId);
        CustInfo custInfo = new CustInfo();
        List<SysDept> deptList = isysDeptService.selectChildrenAllDeptById(sysUser.getDeptId());
        Map<String, Object> ids_map = userInfoComm.getDeptIdsEmpIdsByDepts(deptList);
        Long[] deptIds = (Long[]) MapUtils.getObject(ids_map, "deptIds");
        if (deptIds.length > 0) {
            custInfo.setDeptIds(deptIds);
        }
        Long[] empIds = (Long[]) MapUtils.getObject(ids_map, "empIds");
        if (empIds.length > 0) {
            custInfo.setUserIds(empIds);
        }
        custInfo.setIsDelete("0");
        custInfo.setStatus("0");
        //查询所有跟进中的客户
        List<CustInfo> listCust = iCustInfoService.selectCustInfoList(custInfo);
        for (CustInfo info : listCust) {
            if (StatusConstant.DISTRIBUTE_STATUS_RE.equals(info.getReDistributeStatus())) {
                reNum++;
            } else if (StatusConstant.DISTRIBUTE_STATUS_MUST.equals(info.getReDistributeStatus())) {
                mustNum++;
            }
        }
        totalNum = listCust.size();
        result.put("totalNum", totalNum);
        result.put("myNum", listCust.size());
        result.put("reNum", reNum);
        result.put("mustNum", mustNum);

        return AjaxResult.success(result);
    }


    /**
     * 获取所有未指派数据
     *
     * @return
     */
    @GetMapping("/getNotAssignedCust/{userId}")
    public AjaxResult getNotAssignedCust(@PathVariable Long userId) {
        Map<String, Object> result = new HashMap<String, Object>();
        SysUser sysUser = iSysUserService.selectUserById(userId);
        SysDept sysDept = isysDeptService.selectDeptById(sysUser.getDeptId());        //总数
        String city = sysDept.getCity();
        if ("中国".equals(city)) {
            city = null;
        }
        int totalNum = iCustInfoService.countByNotAssigned(city);
        result.put("totalNum", totalNum);
        return AjaxResult.success(result);
    }

}

